package fun.ticsmyc.multiThread;

import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Ticsmyc
 * @date 2020-12-10 10:17
 */
public class 阻塞队列 {
    public static void main(String[] args) {
        MyBlockingQueue<Integer> blockingQueue = new MyBlockingQueue<Integer>(new LinkedList<Integer>(), 3);

        Runnable task1 = ()->{
            for(int i=1;i<10;++i){
                try {
                    blockingQueue.put(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Runnable task2 = ()->{
            for(int i=1;i<10;++i){
                try {
                    blockingQueue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(task1);
        executorService.submit(task2);

    }


}

class MyBlockingQueue<T>{
    private LinkedList<T> queue;
    private int maxSize;
    private ReentrantLock reentrantLock;
    private Condition notFull;
    private Condition notEmpty;

    public MyBlockingQueue(LinkedList<T> queue,int size){
        this.queue=queue;
        this.maxSize = size;
        this.reentrantLock = new ReentrantLock();
        notFull = reentrantLock.newCondition();
        notEmpty = reentrantLock.newCondition();
    }

    public T take() throws InterruptedException {
        reentrantLock.lock();
        while(queue.size() ==0){
            notEmpty.await();
        }
        T res = queue.poll();
        notFull.signal();
        reentrantLock.unlock();
        System.out.println("消费"+res);
        TimeUnit.SECONDS.sleep(2);
        return res;
    }
    public void put(T item) throws InterruptedException {
        reentrantLock.lock();

        while(queue.size() == maxSize){
            notFull.await();
        }
        System.out.println("生产"+ item);
        queue.offer(item);
        notEmpty.signal();
        reentrantLock.unlock();
    }

}
